package demo.dcs;

import demo.java.lang.management.jvm.AppTraceConfig;
import demo.java.lang.management.vo.ClientConstants;
import demo.java.lang.management.vo.XmlySpan;
import demo.java.util.ConcurrentHashSet;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @author buffoon
 * @date 16/5/3
 */
public class DistinctServiceIdHolder {
    private static final Logger logger = LoggerFactory.getLogger(DistinctServiceIdHolder.class);

    //serviceId数量限制
    private Set<String> distinctServiceIds = new ConcurrentHashSet<String>();
    private final AtomicLong httpServiceIdCounter = new AtomicLong(0);

    //采样补偿key数量限制
    private Set<String> distinctSCKeys = new ConcurrentHashSet<String>();
    private final AtomicLong sCKeysCounter = new AtomicLong(0);

    public boolean tooManySCKeys() {
        if (!AppTraceConfig.isInitSuccess()) {
            return false;
        }
        if (sCKeysCounter.get() < AppTraceConfig.getLocalConfig().getDistinctMaxService() * 32) {
            return false;
        } else {
            logger.error("distinct SCKeys number more than " + AppTraceConfig.getLocalConfig().getDistinctMaxService() + ", let xdcs team know.");
            return true;
        }
    }

    public boolean addSCKey(String SCKey) {
        if (SCKey != null) {
            if (tooManySCKeys()) {
                return false;
            }
            boolean addRet = distinctSCKeys.add(SCKey);
            if (addRet) {//返回true表示添加成功，原来set里没有
                sCKeysCounter.incrementAndGet();
            }
        }
        return true;
    }

    public boolean tooManyServiceIds() {
        if (!AppTraceConfig.isInitSuccess()) {
            return false;
        }
        if (httpServiceIdCounter.get() < AppTraceConfig.getLocalConfig().getDistinctMaxService()) {
            return false;
        } else {
            logger.error("distinct serviceId number more than " + AppTraceConfig.getLocalConfig().getDistinctMaxService() + ", let xdcs team know.");
            return true;
        }
    }

    public boolean addServiceId(XmlySpan span) {
        if (tooManyServiceIds()) {
            return false;
        }
        String resultCode = span.getProps().get(ClientConstants.X_B3_RESPONSE_CODE);
        if (StringUtils.startsWith(resultCode, "2") || StringUtils.startsWith(resultCode, "3")) {
            if (span.getServiceId() != null) {
                boolean addRet = distinctServiceIds.add(span.getServiceId());
                if (addRet) {//返回true表示添加成功，原来set里没有
                    httpServiceIdCounter.incrementAndGet();
                }
            }
        }
        return true;
    }


    private static class Holder {
        private static DistinctServiceIdHolder serviceIdHolder = new DistinctServiceIdHolder();
    }

    private DistinctServiceIdHolder() {
    }

    public static DistinctServiceIdHolder getInstance() {
        return Holder.serviceIdHolder;
    }
}
